// Copyright (c) Microsoft Corporation. All rights reserved.

using System;
using System.Globalization;
using System.Runtime.Serialization;
using System.Security.Permissions;

using Microsoft.TeamFoundation.Migration.Toolkit;
using Microsoft.TeamFoundation.WorkItemTracking.Client;

namespace Microsoft.TeamFoundation.Migration.Toolkit.Wit
{
    /// <summary>
    /// Generic WIT exception.
    /// </summary>
    [Serializable]
    public class WitMigrationException : MigrationException
    {
        public WitMigrationException()
            : base()
        {
        }

        public WitMigrationException(string message)
            : base(message)
        {
        }

        public WitMigrationException(string message, Exception innerException)
            : base(message, innerException)
        {
        }

        protected WitMigrationException(SerializationInfo info, StreamingContext context)
            : base(info, context)
        {
        }

        [SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter=true)]
        public override void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            if (info == null)
            {
                throw new ArgumentNullException("info");
            }
            base.GetObjectData(info, context);
            info.SetType(GetType());
        }
    }

    /// <summary>
    /// The exception occurs when the engine encounters an error it cannot handle.
    /// </summary>
    [Serializable]
    public class SynchronizationEngineException : WitMigrationException
    {
        public SynchronizationEngineException()
            : base()
        {
        }

        public SynchronizationEngineException(string message)
            : base(message)
        {
        }

        public SynchronizationEngineException(string message, Exception innerException)
            : base(message, innerException)
        {
        }

        protected SynchronizationEngineException(SerializationInfo info, StreamingContext context)
            : base(info, context)
        {
        }
    }

    /// <summary>
    /// Exception informing that metadata is out of sync.
    /// </summary>
    [Serializable]
    public class MetadataOutOfSyncException : WitMigrationException
    {
        public MetadataOutOfSyncException()
            : base()
        {
        }
        
        public MetadataOutOfSyncException(string message)
            : base(message)
        {
        }

        public MetadataOutOfSyncException(string message, Exception innerException)
            : base(message, innerException)
        {
        }

        protected MetadataOutOfSyncException(SerializationInfo info, StreamingContext context)
            : base(info, context)
        {
        }
    }

    /// <summary>
    /// The exception occurs when a work item on the opposite side no longer exists.
    /// </summary>
    [Serializable]
    public class OrphanedWorkItemException : WitMigrationException
    {
        private FullId m_id;                                // Full id of the orphaned work item.

        public OrphanedWorkItemException(
            FullId id)
            : base(string.Format(Resources.Culture, Resources.ErrorOrphanedWorkItem, id))
        {
            m_id = id;
        }

        public OrphanedWorkItemException()
        {
        }

        public OrphanedWorkItemException(
            string msg)
            : base(msg)
        {
        }

        public OrphanedWorkItemException(
            string msg,
            Exception exception)
            : base(msg, exception)
        {
        }

        protected OrphanedWorkItemException(SerializationInfo info, StreamingContext context)
            : base(info, context)
        {
        }

        /// <summary>
        /// Gets the work item id.
        /// </summary>
        public FullId WorkItemId { get { return m_id; } }

        [SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter = true)]
        public override void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            base.GetObjectData(info, context);
        }
    }

    /// <summary>
    /// Missing path exception.
    /// </summary>
    [Serializable]
    public class MissingPathException : WitMigrationException
    {
        private Node.TreeType m_nodeType;                   // Missing path's type
        private string m_path;                              // Missing path

        /// <summary>
        /// Returns type of the missing path.
        /// </summary>
        public Node.TreeType NodeType { get { return m_nodeType; } }

        /// <summary>
        /// Returns missing path.
        /// </summary>
        public string Path { get { return m_path; } }

        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="nodeType">Type of the missing path</param>
        /// <param name="path">Missing path</param>
        /// <param name="message">Message to be associated with the exception</param>
        public MissingPathException(
            Node.TreeType nodeType,
            string path,
            string message)
            : base(message)
        {
            m_nodeType = nodeType;
            m_path = path;
        }

        public MissingPathException()
        {
        }

        public MissingPathException(
            string message)
            : base(message)
        {
        }

        public MissingPathException(
            string message,
            Exception innerException)
            : base(message, innerException)
        {
        }

        protected MissingPathException(SerializationInfo info, StreamingContext context)
            : base(info, context)
        {
        }

        [SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter = true)]
        public override void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            base.GetObjectData(info, context);
        }
    }
}
